package com.othc0de.helper;

import java.util.Date;
import java.util.Vector;

public class HandleNumberInput {
	
	/** maximale Zeit für eine Klick (zwischen Downn- und Up-Event */
	private final static long KLICK_TIME_SCHWELLE=500;
	
	/** maximale Zeit zwischen zwei Klicks um als Doppelklick gewertet zu werden */
	private final static long DBLKLICK_TIME_SCHWELLE=2000;
	
	/** maximale Koordinatenschwankung um als Klick gewertet zu werden */
	private final static long KLICK_DIST_SCHWELLE=20;
	
	/** minimale Entfernung zwischen zwei zu speichernden Positionen */
	private final static long MOVE_SCHWELLE=1;
	
	/** Distanz zwischen zwei Koordinaten um als Richtung gewertet zu werden */
	private final static long MOVE_DETECT_SCHWELLE=2;
		
	int aktSize=0;
	Vector<Position> positions=new Vector<Position>(100,100);
	int maxX;
	int minX;
	int maxY;
	int minY;
	
	long lastDown;
	long prevDown;
	long lastUp;
	long prevUp;
	
	Vector<IHandleNumberInputListener> inputListener=new Vector<IHandleNumberInputListener>();
	
	public void addListener(IHandleNumberInputListener listener) {
		inputListener.add(listener);
	}

	public void removeListener(IHandleNumberInputListener listener) {
		inputListener.remove(listener);
	}
	
	public void clearListener() {
		inputListener.clear();
	}

	/* wird bei der Instanziierung oder nach einem Wechsel der Orientierung aufgerufen */
	public void resetAndInit() {
		aktSize=0;
		maxX=0;
		maxY=0;
		minX=10000;
		minY=10000;
		lastDown=0;
		lastUp=0;
		prevDown=0;
		prevUp=0;
	}
	
	public void touchDown(float x,float y) {
		prevDown=lastDown;
		lastDown=new Date().getTime();
		addPosition(x, y);
	}

	public void touchUp(float x,float y) {
		prevUp=lastUp;
		lastUp=new Date().getTime();
		// Kontrolle ob die Eingabe komplet gelöscht werden soll - "Doppelklick"
		if (lastUp!=0 && prevUp!=0 &&
				(prevUp-prevDown)<KLICK_TIME_SCHWELLE &&
				(lastUp-prevUp)<KLICK_TIME_SCHWELLE &&
				(lastUp-prevUp)<DBLKLICK_TIME_SCHWELLE &&
				(maxX-minX)<KLICK_DIST_SCHWELLE &&
				(maxY-minY)<KLICK_DIST_SCHWELLE) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.CLEAR);
		}
		else if (isOne()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.ONE);			
		}
		else if (isTwo()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.TWO);			
		}
		else if (isThree()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.THREE);			
		}
		else if (isFour()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.FOUR);			
		}
		else if (isFive()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.FIVE);			
		}
		else if (isSix()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.SIX);			
		}
		else if (isSeven()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.SEVEN);			
		}
		else if (isEight()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.EIGHT);			
		}
		else if (isNine()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.NINE);			
		}
		else if (isZero()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.ZERO);			
		}
		else if (isDel()) {
			resetAndInit();
			notifyListener(IHandleNumberInputListener.InputState.DEL);			
		}
		else if (!isClick()) // wenn es ein einfacher Klick war, dann kann unter Umständen ein zweiter
			// Klick folgen - zum vollständigen Löschen der Eingabe
			resetAndInit();
	}
	
	public void touchMove(float x,float y) {
		addPosition(x,y);
	}
	
	private boolean isOne() {
		int i=0;
		int lastX;
		int lastY;
		for (Position pos:positions) {
			if(i==aktSize) break;
			if (i>0) {
				
			}
			lastX=pos.x;
			lastY=pos.y;
			i++;
		}
		return false; // TODO
	}
	
	private boolean isTwo() {
		/*
		for (Position pos:positions) {
			if(i==aktSize) break;
			// do something
			i++;
		}
		 */
		return false; // TODO
	}

	private boolean isThree() {
		return false; // TODO
	}

	private boolean isFour() {
		return false; // TODO
	}

	private boolean isFive() {
		return false; // TODO
	}

	private boolean isSix() {
		return false; // TODO
	}

	private boolean isSeven() {
		return false; // TODO
	}

	private boolean isEight() {
		return false; // TODO
	}

	private boolean isNine() {
		return false; // TODO
	}

	private boolean isZero() {
		return false; // TODO
	}

	private boolean isClick() {
		return false; // TODO
	}

	private boolean isDel() {
		return false; // TODO
	}

	private void notifyListener(IHandleNumberInputListener.InputState input) {
		for (IHandleNumberInputListener listener:inputListener)
			listener.notify(input);
	}
	
	private void addPosition(float x,float y) {
		if (aktSize==positions.size()) {
			Position pos=new Position(x,y);
			aktSize++;
			positions.add(pos);
		}
		else {
			Position pos=positions.get(aktSize);
			pos.x=(int)x;
			pos.y=(int)y;
			aktSize++;
		}
	}
		
	class Position {
		int x;
		int y;
		Position (float x,float y) {
			this.x=(int)x;
			this.y=(int)y;
			if (this.x>maxX)
				maxX=this.x;
			if (this.x<minX)
				minX=this.x;
			if (this.y>maxY)
				maxY=this.y;
			if (this.y<minY)
				minY=this.y;
		}
	}
}